home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Applications / PICSee Dust 1.01 / Quaternary Source / Class_DynamoArray.cpp < prev    next >
Text File  |  1995-11-22  |  10KB  |  362 lines

  1. /*
  2.     Class_DynamoArray.cpp
  3.  
  4.     Version 2.0
  5.     (c)1993, 1994, 1995 by Hiep Dam. All Rights Reserved.
  6.     From The Witches' Brew
  7.  
  8.     Usage: Public domain. Feel free to exploit it to your own needs; it would
  9.            be nice of you, however, to give me some tiny credits if you decide
  10.            to use this in your application or if the code helps you...
  11. */
  12.  
  13. // ---------------------------------------------------------------------------
  14.  
  15. #include "Class_DynamoArray.h"
  16.  
  17. const short STD_DYNAMO_LEN = 10;    // The standard chunk length the array grows by
  18.  
  19. // ---------------------------------------------------------------------------
  20.  
  21. #pragma mark === CTORs/DTORs ===
  22.  
  23. template <class DynamoArrayType>
  24. DynamoArray<DynamoArrayType>::DynamoArray() {
  25.     // Default constructor; no arguments.
  26.     // This constructor just creates an array with the default size
  27.     // of STD_DYNAMO_LEN (i.e. 10). You can change the standard
  28.     // default size by changing STD_DYNAMO_LEN, if you wish.
  29.     fMaxSize = STD_DYNAMO_LEN;
  30.     fCurSize = 0;
  31.     fArray = new DynamoArrayType[fMaxSize];
  32. } // END constructor
  33.  
  34. // ---------------------------------------------------------------------------
  35.  
  36. template <class DynamoArrayType>
  37. DynamoArray<DynamoArrayType>::DynamoArray(short size) {
  38.     if (size < 1) {
  39.         fMaxSize = STD_DYNAMO_LEN;
  40.         fCurSize = 0;
  41.         fArray = new DynamoArrayType[fMaxSize];
  42.     }
  43.     else {
  44.         fMaxSize = size;
  45.         fCurSize = 0;
  46.         fArray = new DynamoArrayType[fMaxSize];
  47.     }
  48. } // END constructor
  49.  
  50. // ---------------------------------------------------------------------------
  51.  
  52. template <class DynamoArrayType>
  53. DynamoArray<DynamoArrayType>::~DynamoArray() {
  54.     if (fArray != NULL)
  55.         delete []fArray;
  56. } // END destructor
  57.  
  58. // ---------------------------------------------------------------------------
  59.  
  60. template <class DynamoArrayType>
  61. void DynamoArray<DynamoArrayType>::IncreaseSize() {
  62.     // Increase array length/size
  63.     fMaxSize += STD_DYNAMO_LEN;
  64.  
  65.     // Now create newly-sized array
  66.     DynamoArrayType *temp = new DynamoArrayType[fMaxSize];
  67.     if (temp == NULL) {
  68.         // Insert c++ exception here.
  69.     }
  70.  
  71.     // Copy items from old array into newly-created array
  72.     for (short i = 0; i < fCurSize; i++)
  73.         temp[i] = fArray[i];
  74.  
  75.     // Delete original copy.
  76.     delete fArray;
  77.  
  78.     fArray = temp;
  79. } // END IncreaseSize
  80.  
  81. //-------------------------------------------------------------
  82.  
  83. // Copy *Constructor*. Remember, this is a constructor
  84. // so the fields of the array are invalid when we begin
  85.  
  86. template <class DynamoArrayType>
  87. DynamoArray<DynamoArrayType>::DynamoArray(DynamoArray& sourceArray) {
  88.     if (&sourceArray == this) return;    // Don't copy with references to self
  89.  
  90.     fCurSize = sourceArray.fCurSize;
  91.     fMaxSize = 0;
  92.  
  93.     while (fMaxSize < fCurSize)
  94.         fMaxSize += STD_DYNAMO_LEN;    // Increase it in chunks of STD_DYNAMO_LEN
  95.  
  96.     fArray = new DynamoArrayType[fMaxSize];
  97.     if (fArray == NULL) {
  98.         // Insert c++ exception here
  99.     }
  100.  
  101.     for (short i = 0; i < fCurSize; i++)
  102.         fArray[i] = sourceArray.fArray[i];
  103. } // END Copy constructor
  104.  
  105. //-------------------------------------------------------------
  106.  
  107. #pragma mark === Operators ===
  108.  
  109. // Assignment operator (overloaded)
  110.  
  111. template <class DynamoArrayType>
  112. DynamoArray DynamoArray<DynamoArrayType>::operator=(const DynamoArray& sourceArray) {
  113.     if (&sourceArray == this) return(*this);    // Don't assign with references to self
  114.  
  115.     // Make a copy, so trash whatever we have currently. Unfortunately
  116.     // we can't make a call to the destructor, so we have to do this manually...
  117.     delete []fArray;
  118.  
  119.     // Now make a new array
  120.     fArray = new DynamoArrayType[fMaxSize = sourceArray.fMaxSize];
  121.     if (fArray == NULL) {
  122.         // Insert c++ exception here
  123.     }
  124.     fCurSize = sourceArray.fCurSize;
  125.  
  126.     // Do the actual copy...
  127.     for (short i = 0; i < fCurSize; i++)
  128.         fArray[i] = sourceArray.fArray[i];
  129.  
  130.     return(*this);    // return a copy of this object
  131. } // END Assignment operator
  132.  
  133. //-------------------------------------------------------------
  134.  
  135. template <class DynamoArrayType>
  136. DynamoArrayType *DynamoArray<DynamoArrayType>::operator[] (short index) {
  137.     if ((index < 0) || (index >= fCurSize))
  138.         return NULL;
  139.     else
  140.         return &fArray[index];
  141. } // END operator[]
  142.  
  143. //-------------------------------------------------------------
  144.  
  145. #pragma mark === Member Funcs ===
  146.  
  147. template <class DynamoArrayType>
  148. void DynamoArray<DynamoArrayType>::Preallocate(short size) {
  149.         /* This makes the array the specified size; note that
  150.            the old array is destroyed - it's contents are lost.
  151.            So make sure you call this first before adding any
  152.            data to the array.
  153.         */
  154.  
  155.     delete []fArray;
  156.  
  157.         // Make it a little bigger, just in case
  158.     fMaxSize = size + STD_DYNAMO_LEN;
  159.  
  160.     fArray = new DynamoArrayType[fMaxSize];
  161.     if (fArray == NULL) {
  162.         // Oops. Insert c++ exception here.
  163.     }
  164.  
  165.     fCurSize = 0;
  166. } // END Preallocate
  167.  
  168. //-------------------------------------------------------------
  169.  
  170. template <class DynamoArrayType>
  171. short DynamoArray<DynamoArrayType>::Get(DynamoArrayType& theItem, short index) {
  172.     if ((index < 0) || (index >= fCurSize) || (fArray == NULL))
  173.         // Check for correct boundaries...
  174.         return(kDynamoArrayOutOfBoundsErr);
  175.     else {
  176.         theItem = fArray[index];
  177.         return(index);
  178.     }
  179. } // END GetItem
  180.  
  181. //-------------------------------------------------------------
  182.  
  183. template <class DynamoArrayType>
  184. short DynamoArray<DynamoArrayType>::RandomGet(DynamoArrayType& theItem) {
  185.     if (fCurSize > 0) {
  186.         // Get a random value.
  187.         short randomVal = GetRandom(0, fCurSize - 1);
  188.         // Now retrieve the item.
  189.         short returnVal = Get(theItem, randomVal);
  190.         
  191.         // Did something go wrong? If no...
  192.         if (returnVal >= 0)
  193.             return(randomVal);
  194.         else
  195.             // Ooops, something went wrong; return error value.
  196.             return(returnVal);
  197.         }
  198.     else
  199.         // Oops, array empty.
  200.         return(kDynamoArrayOutOfBoundsErr);
  201. } // END RandomGet
  202.  
  203. //-------------------------------------------------------------
  204.  
  205. template <class DynamoArrayType>
  206. short DynamoArray<DynamoArrayType>::Append(const DynamoArrayType& theItem) {
  207.     if (fArray == NULL) {
  208.         // If array empty, create new one.
  209.         fMaxSize = STD_DYNAMO_LEN;
  210.         fCurSize = 1;
  211.         fArray = new DynamoArrayType[fMaxSize];
  212.     }
  213.     else {
  214.         if (fCurSize == fMaxSize)
  215.             // Ooh, we reached the maximum size. Time to enlarge
  216.             // the array.
  217.             IncreaseSize();
  218.         // We're going to add an item, so increment fCurSize
  219.         fCurSize++;
  220.     }
  221.  
  222.     // Put item into the array.
  223.     fArray[fCurSize - 1] = theItem;
  224.     // Return index value of item we appended into array.
  225.     return(fCurSize - 1);
  226. } // END Append
  227.  
  228. //-------------------------------------------------------------
  229.  
  230. template <class DynamoArrayType>
  231. short DynamoArray<DynamoArrayType>::Insert(const DynamoArrayType& theItem, short index) {
  232.     if ((index < 0) || (index > fCurSize) || (fArray == NULL))
  233.         return(kDynamoArrayOutOfBoundsErr);
  234.     
  235.     if (fCurSize + 1 == fMaxSize)
  236.         // Reached maximum size, so enlarge the array.
  237.         IncreaseSize();
  238.  
  239.     // OK, make room for our new item! Shift everything down from
  240.     // location on to the end of the array.
  241.     for (short i = fCurSize - 1; i >= index; i--)
  242.         fArray[i + 1] = fArray[i];
  243.     
  244.     // Add our new item.
  245.     fArray[index] = theItem;
  246.  
  247.     // We're adding an item, so increment the number of items in array.
  248.     fCurSize++;
  249.     
  250.     return(index);    // Everything OK, so return index value.
  251. } // END Insert
  252.  
  253. //-------------------------------------------------------------
  254.  
  255. template <class DynamoArrayType>
  256. short DynamoArray<DynamoArrayType>::Delete(short index) {
  257.     if ((index < 0) || (index >= fCurSize) || (fArray == NULL))
  258.         return(kDynamoArrayOutOfBoundsErr);
  259.     
  260.     // Shift array backwards (down to 0), so we don't lose anything.
  261.     // If user specified last item is the item to be deleted, this loop
  262.     // won't execute. We just decrement fCurSize instead.
  263.     for (short i = index + 1; i < fCurSize; i++) 
  264.         fArray[i - 1] = fArray[i];
  265.  
  266.     fCurSize--;
  267.     return(index);
  268. } // END Delete
  269.  
  270. //-------------------------------------------------------------
  271.  
  272. template <class DynamoArrayType>
  273. short DynamoArray<DynamoArrayType>::SearchDelete(DynamoArrayType& theItem, short startIndex) {
  274.     short val = kDynamoArrayOutOfBoundsErr;    // Assume did not find item
  275.  
  276.     // Search for the item by value, not by index.
  277.     val = Search(theItem, startIndex);
  278.     if (val >= 0)
  279.         Delete(val);    // We found it, so delete!
  280.  
  281.     return val;
  282. } // END SearchDelete
  283.  
  284. //-------------------------------------------------------------
  285.  
  286. template <class DynamoArrayType>
  287. short DynamoArray<DynamoArrayType>::Remove(DynamoArrayType& theItem, short index) {
  288.     if ((index < 0) || (index >= fCurSize) || (fArray == NULL))
  289.         return(kDynamoArrayOutOfBoundsErr);
  290.     else {
  291.         // In previous versions, Remove() just returned the address of the item
  292.         // that was "deleted". Problem was, the address was no longer pointing
  293.         // to the item that was deleted, but pointed to the item replacing
  294.         // the deleted item!!
  295.         if (Get(theItem, index) != kDynamoArrayOutOfBoundsErr) {
  296.             if (Delete(index) != kDynamoArrayOutOfBoundsErr) {
  297.                 return(index);
  298.             }
  299.         }
  300.         return(kDynamoArrayOutOfBoundsErr);
  301.     }
  302. } // END Remove
  303.  
  304. //-------------------------------------------------------------
  305.  
  306. template <class DynamoArrayType>
  307. short DynamoArray<DynamoArrayType>::RandomRemove(DynamoArrayType& theItem) {
  308.     return Remove(theItem, GetRandom(0, fCurSize - 1));
  309. } // END RandomRemove
  310.  
  311. //-------------------------------------------------------------
  312.  
  313. template <class DynamoArrayType>
  314. short DynamoArray<DynamoArrayType>::Search(const DynamoArrayType& source, short startIndex) {
  315.     // Assume we haven't found our baby...
  316.     short foundItem = kDynamoArrayOutOfBoundsErr;
  317.  
  318.     if (startIndex >= fCurSize)
  319.         return(foundItem);
  320.  
  321.     for (short i = startIndex; i < fCurSize; i++) {
  322.         if (fArray[i] == source) {
  323.             // Yeah, found it. Set return value and exit loop.
  324.             foundItem = i;
  325.             break;
  326.         }
  327.     }
  328.     return(foundItem);
  329. } // END Search
  330.  
  331.  
  332. // -----------------------------------------------------------------------------
  333.  
  334. // The following routine was "lifted" from Tony Myles' SpriteWorld Package,
  335. // in GameUtils.c
  336. // Great code in SpriteWorld, by the way.
  337.  
  338.  
  339. //    By:    Tony Myles
  340. //    Date:    9/19/90
  341. //    Copyright: © 1991-93 Tony Myles, All rights reserved worldwide.
  342.  
  343. //    GetRandom
  344. //    generate a random number between min and max inclusive
  345. template <class DynamoArrayType>
  346. unsigned short DynamoArray<DynamoArrayType>::GetRandom(unsigned short min, unsigned short max)
  347. {
  348.     unsigned short random;
  349.     long range, temp;
  350.  
  351.     random = Random();
  352.     range = (max - min) + 1;
  353.     temp = (random * range) / 65536;
  354.     random = temp + min;
  355.  
  356.     return random;
  357. }
  358.  
  359. // -----------------------------------------------------------------------------
  360.  
  361.  
  362. // END DynamoArray.c++